Noviembre 06 de 2020

Introducción

Una de las ramas más importantes del Machine Learning y la Inteligencia Artificial son las redes neuronales. Las redes neuronales (neural networks) son una representación abstracta del comportamiento de una red neuronal biológica. Su contexto se remonta a 1943, año en el cual McCulloch y Pitts proponen el primer modelo neuronal, dicho modelo era un modelo binario, en el cual cada neurona tenía un escalón o umbral prefijado. De esta manera sirvió de base para los modelos posteriores.

Conceptos

Neurona biológica: Es una célula del sistema nervioso central que posee la capacidad de recibir y decodificar información en forma de señales eléctricas y químicas, transmitiéndolas a otras células.

Neurona artificial: Es la unidad básica de una red neuronal, tratan de imitar el funcionamiento de las neuronas de los organismos vivos.

Red Neuronal: Son un modelo inspirado en el comportamiento biológico. Consiste en un conjunto de neuronas artificiales, conectadas entre sí para transmitir señales.

Sus partes son:

  • Dendritas: Constituyen el canal de entrada de la información.

  • Sinapsis: Conexión entre neuronas.

  • Cuerpo celular (Soma): Es el órgano de cómputo.

  • Axón: Corresponde al canal de salida.

Redes neuronales

De acuerdo a su estructura las redes neuronales se clasifican en:

  • Redes monocapa: Compuestas por una única capa de neuronas.

  • Redes multicapa: Las neuronas se organizan en varias capas.

Estructura

Capas

Las redes neuronales están compuestas por capas de neuronas que se comunican entre si y es posible dividirlas de la siguiente manera:

  • Capa de entrada: Contiene todas nuestras entradas o datos de entrenamiento, estos contarán con pesos que permitirán expresar su importancia.

  • Capa oculta: Puede estar conformada a su vez por una o varias capas, el número de capas dependerá de qué tan sofisticado queremos nuestro modelo. Sin embargo, es necesario recalcar que mientras más capas se tengan necesitaremos más recursos como tiempo y poder computacional.

  • Capa de salida: Se encarga de entregar los resultados, puede contar con una o varias neuronas, dependerá del número de características que se desean llegar a encontrar.

Entradas, pesos, suma ponderada y salida

  • Entradas \((x_{j})\): Las entradas reciben los datos de otras neuronas.

  • Pesos sinápticos \((w_{ij})\): Se hace una asignación de pesos pequeños generados de forma aleatoria, en un rango de valores entre \(-0.5\) y \(0.5\) o algo similar.

  • Función base: Es una función que corresponde a una combinación lineal del conjunto de entradas y los pesos sinápticos. Es decir:

\[u_{i}(w,x)=\sum_{j=1}^{n}w_{ij}x_{j}\]

\(i=1,...,m\) \(j=1,...,n\)

Sesgo “Bias” \((b, w_{0})\)

Ayuda a mover la línea que divide los datos de cada neurona, si el valor de \(b\) es cero, la línea pasa por el origen, dependiendo del número que tenga este parámetro es por donde pasará la línea que divide a los datos.

\[u_{i}(w,x)=\sum_{j=1}^{n}w_{ij}x_{j} \longrightarrow z=b+\sum_{j=1}^{n}w_{ij}x_{j} \]

Función de activación \(\sigma(z)\)

Función de activación \(\sigma(z)\)

Nota: Se debe considerar que en la red neuronal se usará una función no lineal debido a que le permite al modelo adaptarse para trabajar con la mayor cantidad de datos.

Las funciones de activación se dividen en dos tipos como: lineal y no lineal

  • Función lineal

  • Funciones no lineales:

    • Sigmoide

    • Umbral

    • Tangente hiperbólica

    • ReLu

    • Softmax

Aprendizaje automático

Algoritmo Backpropagation

  1. Asignamos a cada conexión neuronal un peso con un valor pequeño, pero no nulo.

  2. Introducimos la primera observación de nuestro conjunto de entrenamiento por la capa inicial de la red neuronal.

  3. La información se propaga de izquierda a derecha, activando cada neurona que ahora es afectada por el peso de cada conexión, hasta llegar a la capa de neuronas de salida, obteniendo el resultado final para esa observación en concreto.

  4. Medimos el error que hemos cometido para esa observación.

  5. Comienza la propagación hacia atrás de derecha a izquierda, actualizando los pesos de cada conexión neuronal, dependiendo de la responsabilidad del peso actualizado en el error cometido.

  6. Repetimos los pasos desde el paso 2, actualizando todos los pesos para cada observación o conjunto de observaciones de nuestro conjunto de entrenamiento.

  7. Cuando todas las observaciones del conjunto de entrenamiento ha pasado por la red neuronal, hemos completado lo que se denomina un Epoch. Podemos realizar tantos Epochs como creamos convenientes.

Aprendizaje automático

Algunos problemas en el entrenamiento de las redes neuronales

  • Valores iniciales: Se hace referencia a los valores que los pesos iniciales pueden tomar. Así, es recomendable llevar acabo una asignación de pesos pequeños generados de forma aleatoria.

\[w_{ij} \in (-0.5,0.5)\]

  • Sobreajuste: También denominado “overfitting”, se produce cuando un sistema de aprendizaje automático se entrena demasiado o con datos anómalos, que hace que el algoritmo aprenda patrones que no son generales.
  • Escalado de las entradas: Es preferible estandarizar todas las entradas para que tengan una media de cero y una desviación estándar de uno.

\[\tilde{x}_{i}=\displaystyle{\frac{(x_{i}-\bar{x}_{i})}{sd}}\]

  • Número de capas y unidades ocultas: El número de unidades ocultas está directamente relacionado con las capacidades de la red. En general, es mejor tener demasiadas unidades ocultas que muy pocas.

Aplicaciones

La mayoría de las aplicaciones de las redes neuronales consisten en:

Finanzas: Previsión de la evolución de los precios, Valoración del riesgo de los créditos, Identificación de falsificaciones, Interpretación de firmas.

Manufacturación: Robots automatizados y sistemas de control (visión artificial y sensores de presión, temperatura, gas, etc.), Inspección de la calidad.

Militares: Clasificación de las señales de radar y Reconocimiento y seguimiento en el tiro al blanco.

Medicina: Clasificación de imágenes para detectar células cancerígenas.

Medio ambiente: Analizar tendencias y patrones.

Ejemplo de aplicación

Datos

Se hará uso del conjunto de datos denominado: “Boston” perteneciente al paquete MASS. El conjunto de datos de Boston es una colección de datos sobre el valor de las viviendas en los suburbios de Boston. Nuestro objetivo es predecir el valor medio de las viviendas ocupadas por sus propietarios (medv) utilizando todas las demás variables continuas disponibles.

set.seed(500)
suppressMessages(library(MASS))
suppressMessages(library(neuralnet))
data <- Boston # Este set de datos pertenece 
               # a la librerías MASS, es un conjunto de datos de pruebas que ésta posee
index <- sample(1:nrow(data),round(0.75*nrow(data)))# se toma una muestra aleatoria
train <- data[index,] # función de entrenamiento
test <- data[-index,] # función de prueba
lm.fit <- glm(medv~., data=train)
pr.lm <- predict(lm.fit,test)
MSE.lm <- sum((pr.lm - test$medv)^2)/nrow(test)

summary(lm.fit)
## 
## Call:
## glm(formula = medv ~ ., data = train)
## 
## Deviance Residuals: 
##      Min        1Q    Median        3Q       Max  
## -15.2113   -2.5587   -0.6552    1.8275   29.7110  
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  31.111702   5.459811   5.698 2.49e-08 ***
## crim         -0.111372   0.033256  -3.349 0.000895 ***
## zn            0.042633   0.014307   2.980 0.003077 ** 
## indus         0.001483   0.067455   0.022 0.982473    
## chas          1.756844   0.981087   1.791 0.074166 .  
## nox         -18.184847   4.471572  -4.067 5.84e-05 ***
## rm            4.760341   0.480472   9.908  < 2e-16 ***
## age          -0.013439   0.014101  -0.953 0.341190    
## dis          -1.553748   0.218929  -7.097 6.65e-12 ***
## rad           0.288181   0.072017   4.002 7.62e-05 ***
## tax          -0.013739   0.004060  -3.384 0.000791 ***
## ptratio      -0.947549   0.140120  -6.762 5.38e-11 ***
## black         0.009502   0.002901   3.276 0.001154 ** 
## lstat        -0.388902   0.059733  -6.511 2.47e-10 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for gaussian family taken to be 20.23806)
## 
##     Null deviance: 32463.5  on 379  degrees of freedom
## Residual deviance:  7407.1  on 366  degrees of freedom
## AIC: 2237
## 
## Number of Fisher Scoring iterations: 2

Adaptación de la red neuronal

Antes de instalar una red neuronal, es necesario realizar algunos preparativos. Como primer paso, se aborda el preprocesamiento de datos. Aquí se normalizan los datos antes de entrenar la red neuronal.

Se elige el método min-max y se escalan los datos en el intervalo [0,1]. Normalmente, el escalado en los intervalos [0,1] o [-1,1] tiende a dar mejores resultados. Por lo tanto, escalamos y dividimos los datos antes de continuar:

maxs <- apply(data, 2, max) #valores máximos para el entrenamiento
mins <- apply(data, 2, min) #valores mínimos para el entrenamiento
scaled <- as.data.frame(scale(data, center = mins, scale = maxs - mins))
train_ <- scaled[index,]
test_ <- scaled[-index,]
  • Nota: Tener en cuenta que scale devuelve una matriz que necesita ser convertida en un data.frame.

Adaptación de la red neuronal

Parámetros

En esta ocasión, vamos a utilizar 2 capas ocultas con esta configuración:

\[13: 5: 3: 1\]

La capa de entrada tiene 13 entradas, las dos capas ocultas tienen 5 y 3 neuronas y la capa de salida tiene, por supuesto, una única salida ya que estamos haciendo regresión.

n <- names(train_)
f <- as.formula(paste("medv ~", paste(n[!n %in% "medv"], collapse = " + ")))
nn <- neuralnet(f,data=train_,hidden=c(5,3),linear.output=T)
# Red neuronal
plot(nn)

Representación gráfica

El paquete neuralnet proporciona una buena herramienta para trazar el modelo. Esta es la representación gráfica del modelo con los pesos en cada conexión:

Modelo red neuronal

Observaciones

  • Las líneas negras muestran las conexiones entre cada capa y los pesos en cada conexión.

  • Las líneas azules muestran el término de sesgo agregado en cada paso.

  • El sesgo se puede pensar como la intersección de un modelo lineal.

  • Finalmente, el algoritmo de entrenamiento ha convergido y, por lo tanto, el modelo está listo para ser utilizado.

Predicción “medv” usando la red neuronal

Ahora es posible predecir los valores para el conjunto de prueba y calcular el MSE.

pr.nn <- compute(nn,test_[,1:13])

pr.nn_ <- pr.nn$net.result*(max(data$medv)-min(data$medv))+min(data$medv)
test.r <- (test_$medv)*(max(data$medv)-min(data$medv))+min(data$medv)

MSE.nn <- sum((test.r - pr.nn_)^2)/nrow(test_)

Se comparan los dos MSE para el modelo estimado de forma tradicional y por mediante la red neuronal:

print(paste(MSE.lm,MSE.nn))
## [1] "31.2630222372615 16.4595537665717"

Los resultados muestran que la red neuronal está realizando una mejor predicción para los “medv” que el modelo lineal.

Rendimiento de la Red neuronal vs. Modelo lineal

A continuación se muestra un primer enfoque visual del rendimiento de la red y el modelo lineal en el conjunto de prueba.

A partir de la figura anterior es posible evidenciar que las predicciones hechas por la red neuronal están (en general) más concentradas alrededor de la línea (una alineación perfecta con la línea indicaría un MSE de 0 y, por lo tanto, una predicción perfecta ideal) que las realizadas por el modelo lineal.

Rendimiento de la Red neuronal vs. Modelo lineal

A continuación se muestra una comparación visual más útil:

Red neuronal real vs. predicción

Bibliografía

  • Hastie, T., Tibshirani, R., & Friedman, J. (2009). The elements of statistical learning: data mining, inference, and prediction. Springer Science & Business Media.

  • Efron, B., & Hastie, T. (2016). Computer age statistical inference (Vol. 5). Cambridge University Press.

¡Gracias por tu atención!